App.require(["yDate"], function (yDate) {
    var app = App.getCurrent();

    app.definePopUp("pcstrdateRangePicker", {
        computeMinDateTime: function (minDate, minTime, date, time) {
            if (date.compare(minDate) === -1 ||
                (date.compare(minDate) === 0 && 
                (minTime.hour > time.hour || (minTime.hour == time.hour && minTime.minute > time.minute))
            )) return {  time: minTime, date: minDate }
            return null;
        },
        computeMaxDateTime: function (maxDate, maxTime, date, time) {
            if (date.compare(maxDate) === 1 ||
                (date.compare(maxDate) === 0 && 
                (time.hour > maxTime.hour || (maxTime.hour == time.hour && time.minute > maxTime.minute))
            )) return {  time: maxTime, date: maxDate }
            return null;
        },
        limiteMinMax() {
            var data = this.data, startTime = data.startTime, endTime = data.endTime, 
                startDate = data.startYDate, endDate = data.endYDate, minTime = data.minTime, 
                maxTime = data.maxTime, maxDate = data.maxDate, minDate = data.minDate;
            
            var sTime = startTime, eTime = endTime, sDate = startDate, eDate = endDate;
            if (minDate.year) {
                if (this.data.selectTime) {
                    var startObj = this.computeMinDateTime(minDate, minTime, startDate, startTime),
                        endObj = this.computeMinDateTime(minDate, minTime, endDate, endTime);

                    if (startObj) {
                        sTime = startObj.time;
                        sDate = startObj.date;
                    }
                    if (endObj) {
                        eTime = endObj.time;
                        eDate = endObj.date;
                    }
                }
                else {
                    if (minDate.compare(startDate) === 1) {
                        sDate = minDate;
                    }
                    if (minDate.compare(endDate) === 1) {
                        eDate = minDate;
                    }
                }
            }
            if (maxDate.year) {
                if (this.data.selectTime) {
                    var startObj = this.computeMaxDateTime(maxDate, maxTime, startDate, startTime),
                        endObj = this.computeMaxDateTime(maxDate, maxTime, endDate, endTime);

                    if (startObj) {
                        sTime = startObj.time;
                        sDate = startObj.date;
                    }
                    if (endObj) {
                        eTime = endObj.time;
                        eDate = endObj.date;
                    }
                }
                else {
                    if (maxDate.compare(startDate) === -1) {
                        sDate = maxDate;
                    }
                    if (maxDate.compare(endDate) === -1) {
                        eDate = maxDate;
                    }
                }
            }

            return {
                startTime: sTime,
                endTime: eTime,
                startYDate: sDate,
                endYDate: eDate
            }
        },
        hiddenByOutEnv: function () {
            this.hidden();
            var target = this.data.target || app.currentPage;
            target.dispatchEvent("datepickhiddenfromoutenv");
        },
        saveHandler: function (ev) {
            var obj = this.limiteMinMax();
            var target = this.data.target || app.currentPage;
            if (this.data.selectTime) {
                target.dispatchEvent({ type: "datetimerangepickersave", startTime: obj.startTime, endTime: obj.endTime, startDate: obj.startYDate, endDate: obj.endYDate, target: this });
            }
            else {
                target.dispatchEvent({ type: "daterangepickersave", startDate: obj.startYDate, endDate: obj.endYDate, target: this });
            }
            this.hidden();
        },
        closeHandler: function (ev) {
            var obj = this.limiteMinMax();
            var target = this.data.target || app.currentPage;
            if (this.data.selectTime) {
                target.dispatchEvent({ type: "datetimerangepickerclose", startTime: obj.startTime, endTime: obj.endTime, startDate: obj.startYDate, endDate: obj.endYDate, target: this });
            }
            else {
                target.dispatchEvent({ type: "daterangepickerclose", startDate: obj.startYDate, endDate: obj.endYDate, target: this });
            }
            this.hidden();
        },
        clearHandler: function (ev) {
            var obj = this.limiteMinMax();
            var target = this.data.target || app.currentPage;
            if (this.data.selectTime) {
                target.dispatchEvent({ type: "datetimerangepickerclear", startTime: obj.startTime, endTime: obj.endTime, startDate: obj.startYDate, endDate: obj.endYDate, target: this });
            }
            else {
                target.dispatchEvent({ type: "daterangepickerclear", startDate: obj.startYDate, endDate: obj.endYDate, target: this });
            }
            this.hidden();
        },
        initDateByStr: function (str, isTime, isFirst) {
            var date = new yDate(), time = {};
            if (isFirst) {
                this.data.startYDate = date;
                if (isTime) this.data.startTime = time;
            }
            else {
                this.data.endYDate = date;
                if (isTime) this.data.endTime = time;
            }
            if (str) {
                var pattern = isTime ? /(\d+)-(\d+)-(\d+)\s+(\d+):(\d+)/ : /(\d+)-(\d+)-(\d+)/;
                var matches = pattern.exec(str);
                if (matches) {
                    date.year = parseInt(matches[1]);
                    date.month = parseInt(matches[2]);
                    date.day = parseInt(matches[3]);
                    if (isTime) {
                        time.hour = parseInt(matches[4]);
                        time.minute = parseInt(matches[5]);
                    }
                }
            }
            else {
                var current = new Date();
                date.year = current.getFullYear();
                date.month = current.getMonth() + 1;
                date.day = current.getDate();
                if (isTime) {
                    time.hour = current.getHours();
                    time.minute = current.getMinutes();
                }
            }
        },
        setRangeDateByStr: function (str, isTime, isFirst) {
            var date = new yDate(), time = {};
            if (isFirst) {
                this.data.minDate = date;
                if (isTime) this.data.minTime = time;
            }
            else {
                this.data.maxDate = date;
                if (isTime) this.data.maxTime = time;
            }
            if (str) {
                var pattern = isTime ? /(\d+)-(\d+)-(\d+)\s+(\d+):(\d+)/ : /(\d+)-(\d+)-(\d+)/;
                var matches = pattern.exec(str);
                if (matches) {
                    date.year = parseInt(matches[1]);
                    date.month = parseInt(matches[2]);
                    date.day = parseInt(matches[3]);
                    if (isTime) {
                        time.hour = parseInt(matches[4]);
                        time.minute = parseInt(matches[5]);
                    }
                }
            }
        }, 
        setPosition: function () {
            var bindDom = this.data.bindDom;
            if (bindDom) {
                var rect = bindDom.getBoundingClientRect();
                var popDiv = this.popDiv;
                popDiv.style.left = rect.left + "px";
                if (window.innerHeight > rect.bottom + 280) {
                    popDiv.style.top = (rect.bottom + 5) + "px";
                }
                else {
                    popDiv.style.bottom = (window.innerHeight - rect.top + 5) + "px";
                }
            }
        },
        beforeShow: function () {
            if (document.activeElement) document.activeElement.blur();
            var data = this.data;
            this.initDateByStr(data.startDate, data.selectTime, true);
            this.initDateByStr(data.endDate, data.selectTime);
            this.setRangeDateByStr(data.min, data.selectTime, true);
            this.setRangeDateByStr(data.max, data.selectTime);

            data.selectStartDate = {
                year: data.startYDate.year,
                month: data.startYDate.month,
                day: data.startYDate.day
            }
            data.selectEndDate = {
                year: data.endYDate.year,
                month: data.endYDate.month,
                day: data.endYDate.day
            }

            this.setPosition();
            this.attachDiyEvent("save", this.saveHandler);
            this.attachDiyEvent("close", this.closeHandler);
            this.attachDiyEvent("clear", this.clearHandler);
            return true;
        },
    })
});